package com.luyang.platform.contact.domain.user.model;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.luyang.framework.ddd.domain.AggregateRoot;
import com.luyang.platform.contact.domain.user.valueobject.Area;
import com.luyang.platform.contact.domain.user.valueobject.Email;
import com.luyang.platform.contact.domain.user.valueobject.EmployeeNo;
import com.luyang.platform.contact.domain.user.valueobject.Mobile;
import com.luyang.platform.contact.domain.user.valueobject.Name;
import com.luyang.platform.contact.domain.user.valueobject.UserId;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.io.Serial;
import java.time.OffsetDateTime;
import java.util.Arrays;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 用户聚合根
 *
 * @author lu_yang
 */
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class User implements AggregateRoot {

    @Serial
    private static final long serialVersionUID = 8664975505445163210L;

    /**
     * 用户ID
     */
    private UserId userId;

    /**
     * 姓名
     */
    private Name name;

    /**
     * 英文名
     */
    private String enName;

    /**
     * 别名
     */
    private String nickname;

    /**
     * 工号
     */
    private EmployeeNo employeeNo;

    /**
     * 员工类型
     */
    private String employeeType;

    /**
     * 邮箱
     */
    private Email email;

    /**
     * 手机号
     */
    private Mobile mobile;

    /**
     * 性别
     */
    private String gender;

    /**
     * 直接上级ID
     */
    private UserId leaderUserId;

    /**
     * 地区
     */
    private Area area;

    /**
     * 入职日期
     */
    private OffsetDateTime joinDate;

    /**
     * 创建工号
     *
     * @param area 地区
     * @author lu_yang
     */
    public void createEmployeeNo(Area area) {
        var country = area.country();
        Assert.notBlank(country, "国家或地区Code为空");
        // TODO: 2022/5/14 获取工号流水 暂用随机数替代 疑问:如何调用基础层从Redis中获取流水号
        var employee = RandomUtil.randomNumbers(6);
        this.employeeNo = new EmployeeNo(country.toUpperCase(Locale.ROOT).concat(employee));
    }

    /**
     * 创建邮箱 仅限中文<br/>
     * <pre>
     *     郭靖 -> jing.guo@xxx.com
     *     洪七公 -> qigong.hong@xxx.com
     *     一灯大师 -> dashi.yideng@xxx.com
     * </pre>
     *
     * @param name 姓名
     * @author lu_yang
     */
    public void createEmail(Name name) {
        var nameVar = name.value();
        Assert.isTrue(Validator.isChinese(nameVar), "仅限中文可创建邮箱号");

        var nameChars = PinyinUtil.getPinyin(nameVar).split(CharSequenceUtil.SPACE);
        Stream<String> stream = Arrays.stream(nameChars);

        this.email = new Email(
            (nameChars.length <= 3)
                ? String.format("%s.%s@xxx.com", stream
                    .skip(1)
                    .collect(Collectors.joining(CharSequenceUtil.EMPTY)), nameChars[0])
                : String.format("%s.%s%s@xxx.com", stream
                    .skip(2)
                    .collect(Collectors.joining(CharSequenceUtil.EMPTY)), nameChars[0], nameChars[1])
        );
    }
}
